﻿using System;
using System.Collections.Generic;
using PhiStore.ObjectManaging;

namespace PhiStore.Communication
{
    class LockManager
    {
        Dictionary<string, ObjectLock> objectEntries;
        Queue<LockManagerEntry> timestamps;
        public LockManager()
        {
            objectEntries = new Dictionary<string, ObjectLock>();
            timestamps = new Queue<LockManagerEntry>();
        }

        public void SaveLock(string key, ObjectLock locked)
        {
            Log.Instance.AddLogEntry("LockManager", "Storing lock for " + key);
            objectEntries.Add(key, locked);
            
            LockManagerEntry entry = new LockManagerEntry();
            entry.Key = key;
            entry.Timestamp = DateTime.Now;
            timestamps.Enqueue(entry);
            
        }

        public ObjectLock FetchLock(string key)
        {
            Log.Instance.AddLogEntry("LockManager", "Fetching lock for " + key);
            ObjectLock result = objectEntries[key];
            objectEntries.Remove(key);
            return result;
        }

        public List<string> GetDeadKeys()
        {
            List<string> deadKeys = new List<string>();
            bool cont = true;
            while (cont)
            {
                if (timestamps.Count == 0)
                    cont = false;
                else
                {
                    LockManagerEntry head = timestamps.Peek();
                    if (!objectEntries.ContainsKey(head.Key))
                    {
                        timestamps.Dequeue();
                    }
                    else if (head.Timestamp.AddSeconds(30) < DateTime.Now)
                    {
                        deadKeys.Add(head.Key);
                        timestamps.Dequeue();
                    }
                    else
                    {
                        cont = false;
                    }
                }
            }
            return deadKeys;
        }

        public List<string> GetAllLocks()
        {
            return new List<string>(objectEntries.Keys);
        }
    }

    struct LockManagerEntry
    {
        public string Key;
        public DateTime Timestamp;
    }
    
}
